
#include "core/olisp_core.h"
#include "core/olisp_mem.h"

typedef struct str_impl_t
{
    str_obj_vtbl_t * vtbl;
    
    int ref_count;

    char str[1];
} str_impl_t;

static int str_add_ref( str_obj_t * self )
{
    str_impl_t * s = (str_impl_t *)self;
    return ++s->ref_count;
}

static int str_release( str_obj_t * self )
{
    str_impl_t * s = (str_impl_t *)self;
    int res = --s->ref_count;
    
    if( res > 0 )
        return res;

    lisp_free( s );
    return 0;
}

static const char * str_get_str( str_obj_t * self )
{
    str_impl_t * s = (str_impl_t *)self;
    return s->str;
}

static str_obj_vtbl_t str_obj_vtbl =
{
    LISP_ELEM_STRING,
    &str_add_ref,
    &str_release,

    &str_get_str
};

str_obj_t * create_string( const char * str )
{
    size_t total_len = sizeof(str_impl_t) + strlen(str);
    str_impl_t * s = lisp_malloc( total_len );
    if( s )
    {
        s->ref_count = 1;
        s->vtbl = &str_obj_vtbl;
        strcpy( s->str, str );

        return (str_obj_t *)s;
    }

    return 0;
}

